package com.team.engine.util;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 根据表单对象，为业务对象赋值<br/>
 * 表单对象来自request.getParameterMap()<br/>
 * 示例：
 * <pre>
 * AttributeMapping<\Test1\> attributeMapping = new AttributeMapping<\Test1\>(Test1.class);
 * attributeMapping.setPattern("yyyy-MM-dd"); //当有日期类型时
 * Test1 mapping = attributeMapping.mapping(map);
 * </pre>
 * @author MengLH
 * @data 2010-9-8
 * @param <T> 业务对象（BO，DTO）
 */
public class AttributeMapping<T> {

	/**
	 * 需要装填赋值的业务对象（BO，DTO）
	 */
	private Class clazz;
	
	/**
	 * 来自页面的表单对象
	 */
	private Map<String, String[]> map;
	
	/**
	 * 日期和时间的格式
	 */
	private String pattern;
	
	private SimpleDateFormat simpleDateFormat;
	
	public void setPattern(String pattern) {
		this.pattern = pattern;
		this.simpleDateFormat = new SimpleDateFormat(pattern);
	}

	public AttributeMapping(Class clazz){
		this.clazz = clazz;
	}
	
	private Map<String, Object> fieldPool(Map<String, String[]> map){
		
		HashMap<String, Object> fieldPool = new HashMap<String, Object>();
		
		try {
			fieldPool.put("root", (T) this.clazz.newInstance());
			
			for (Entry<String, String[]> entrySet : map.entrySet()) {
				String key = entrySet.getKey();
				String[] keySplit = null;
				if (key.contains(".")) {
					keySplit = key.split("\\.");
					for (int i = 0; i < keySplit.length; i++) {
						if (i == keySplit.length - 1)
							break;

						String keyTmp = keySplit[i];
						Object object = fieldPool.get(keyTmp);
						if (object == null) {
							Object objectParent = fieldPool
									.get(i - 1 == -1 ? "root" : keySplit[i - 1]);
							
							Field fTmp = objectParent.getClass().getDeclaredField(keyTmp);
							fTmp.setAccessible(true);
							fieldPool.put(keyTmp, (Object) Class.forName(
									fTmp.getType().getName()).newInstance());
						}
					}
				}
			}
					
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
		
		return fieldPool;
	}
	
	/**
	 * 根据表单对象，为业务对象赋值
	 * @param map 表单对象
	 * @return
	 */
	public T mapping(Map<String, String[]> map){
		Map<String, Object> fieldPool = this.fieldPool(map);
		
		try {
			for (Entry<String, String[]> entrySet : map.entrySet()) {
				String[] keyArr = entrySet.getKey().split("\\.");
				int length = keyArr.length;
				
				Object object = fieldPool.get(length==1?"root":keyArr[length-2]);
				Field f = object.getClass().getDeclaredField(keyArr[length-1]);
				f.setAccessible(true);
				String typeName = f.getType().getSimpleName();
				
				if (typeName.equals("String"))
					f.set(object, entrySet.getValue()[0]);
				if (typeName.equals("int") || typeName.equals("Integer"))
					f.set(object, Integer.valueOf(entrySet.getValue()[0]));
				if (typeName.equals("long") || typeName.equals("Long"))
					f.set(object, Long.valueOf(entrySet.getValue()[0]));
				if(typeName.equals("Date")){
					Date date = this.simpleDateFormat.parse(entrySet.getValue()[0]);
					f.set(object, date);
				}
				
				for (int i = keyArr.length - 2; i >= 0; i--) {
					String keyParent = i != 0 ? keyArr[i - 1] : "root";
					String key2 = keyArr[i];

					Object objectParent = fieldPool.get(keyParent);
					object = i==keyArr.length - 2?object:fieldPool.get(key2);

					Field f2 = objectParent.getClass().getDeclaredField(key2);
					f2.setAccessible(true);
					f2.set(objectParent, object);
				}
			}
			
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		
		return (T) fieldPool.get("root");
	}
	
	public static void main(String[] args) {
		Map<String, String[]> map = new HashMap<String, String[]>();
		map.put("id", new String[]{"123456"});
		map.put("tUser.name", new String[]{"a1"});
		map.put("tUser.email", new String[]{"a1@ff.com"});
		map.put("tUser.phone", new String[]{"123"});
		map.put("tUser.password", new String[]{"111"});
		map.put("tUser.registerTime", new String[]{"2010-09-06"});
		map.put("tUsergroup.name", new String[]{"g1"});
		map.put("tUsergroup.explain", new String[]{"aaaaaaaaaaaaaa"});
//		map.put("tUser.tUserDetails.surname", new String[]{"哈哈"});
//		map.put("tUser.tUserDetails.sex", new String[]{"1"});
		
//		AttributeMapping<Test1> attributeMapping = new AttributeMapping<Test1>(Test1.class);
//		attributeMapping.setPattern("yyyy-MM-dd");
//		Test1 mapping = attributeMapping.mapping(map);
//		System.out.println(mapping.gettUser().gettUserDetails().getSurname());
//		System.out.println(mapping.gettUser().getRegisterTime());
//		System.out.println(mapping.getId());
		
	}
	
}
